from dataclasses import dataclass
from datetime import datetime
from typing import Optional, Dict, Any, List


@dataclass
class LoginCredentials:
    """登录凭据"""
    username: str
    password: str
    extra: Optional[Dict[str, Any]] = None  # 额外参数，如验证码、二步验证等
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "username": self.username,
            "password": self.password,
            "extra": self.extra or {}
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "LoginCredentials":
        """从字典创建"""
        return cls(
            username=data["username"],
            password=data["password"],
            extra=data.get("extra")
        )


@dataclass
class PersistentLoginInfo:
    """持久化登录信息，用于下次免密登录"""
    provider: str  # 提供商名称
    user_id: Optional[str] = None  # 用户ID
    access_token: Optional[str] = None  # 访问令牌
    refresh_token: Optional[str] = None  # 刷新令牌
    expires_at: Optional[datetime] = None  # 过期时间
    extra: Optional[Dict[str, Any]] = None  # 额外信息
    
    def is_expired(self) -> bool:
        """检查是否已过期"""
        if self.expires_at is None:
            return False
        return datetime.now() > self.expires_at
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "provider": self.provider,
            "user_id": self.user_id,
            "access_token": self.access_token,
            "refresh_token": self.refresh_token,
            "expires_at": self.expires_at.isoformat() if self.expires_at else None,
            "extra": self.extra or {}
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "PersistentLoginInfo":
        """从字典创建"""
        expires_at = None
        if data.get("expires_at"):
            expires_at = datetime.fromisoformat(data["expires_at"])
        
        return cls(
            provider=data["provider"],
            user_id=data.get("user_id"),
            access_token=data.get("access_token"),
            refresh_token=data.get("refresh_token"),
            expires_at=expires_at,
            extra=data.get("extra")
        )


@dataclass
class CloudFile:
    """云文件信息"""
    file_id: str  # 文件ID
    name: str  # 文件名
    path: str  # 完整路径
    size: int  # 文件大小（字节）
    is_folder: bool  # 是否为文件夹
    parent_id: Optional[str] = None  # 父文件夹ID
    created_at: Optional[datetime] = None  # 创建时间
    modified_at: Optional[datetime] = None  # 修改时间
    md5: Optional[str] = None  # MD5哈希
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "file_id": self.file_id,
            "name": self.name,
            "path": self.path,
            "size": self.size,
            "is_folder": self.is_folder,
            "parent_id": self.parent_id,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "modified_at": self.modified_at.isoformat() if self.modified_at else None,
            "md5": self.md5
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "CloudFile":
        """从字典创建"""
        created_at = None
        if data.get("created_at"):
            created_at = datetime.fromisoformat(data["created_at"])
        
        modified_at = None
        if data.get("modified_at"):
            modified_at = datetime.fromisoformat(data["modified_at"])
        
        return cls(
            file_id=data["file_id"],
            name=data["name"],
            path=data["path"],
            size=data["size"],
            is_folder=data["is_folder"],
            parent_id=data.get("parent_id"),
            created_at=created_at,
            modified_at=modified_at,
            md5=data.get("md5")
        )


@dataclass
class AccountInfo:
    """账户信息"""
    user_id: str  # 用户ID
    username: str  # 用户名
    nickname: Optional[str] = None  # 昵称
    avatar_url: Optional[str] = None  # 头像URL
    email: Optional[str] = None  # 邮箱
    phone: Optional[str] = None  # 手机号
    total_space: Optional[int] = None  # 总空间（字节）
    used_space: Optional[int] = None  # 已用空间（字节）
    extra: Optional[Dict[str, Any]] = None  # 额外信息
    
    def get_free_space(self) -> Optional[int]:
        """获取剩余空间（字节）"""
        if self.total_space is not None and self.used_space is not None:
            return self.total_space - self.used_space
        return None
    
    def get_usage_percentage(self) -> Optional[float]:
        """获取使用率百分比"""
        if self.total_space is not None and self.used_space is not None and self.total_space > 0:
            return (self.used_space / self.total_space) * 100
        return None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "user_id": self.user_id,
            "username": self.username,
            "nickname": self.nickname,
            "avatar_url": self.avatar_url,
            "email": self.email,
            "phone": self.phone,
            "total_space": self.total_space,
            "used_space": self.used_space,
            "extra": self.extra or {}
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "AccountInfo":
        """从字典创建"""
        return cls(
            user_id=data["user_id"],
            username=data["username"],
            nickname=data.get("nickname"),
            avatar_url=data.get("avatar_url"),
            email=data.get("email"),
            phone=data.get("phone"),
            total_space=data.get("total_space"),
            used_space=data.get("used_space"),
            extra=data.get("extra")
        )


@dataclass
class TrashItem:
    """回收站项目"""
    file_id: str  # 文件ID
    name: str  # 文件名
    path: str  # 完整路径
    size: int  # 文件大小（字节）
    is_folder: bool  # 是否为文件夹
    deleted_at: datetime  # 删除时间
    parent_id: Optional[str] = None  # 父文件夹ID
    created_at: Optional[datetime] = None  # 创建时间
    modified_at: Optional[datetime] = None  # 修改时间
    md5: Optional[str] = None  # MD5哈希
    expires_at: Optional[datetime] = None  # 过期时间（永久删除时间）
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "file_id": self.file_id,
            "name": self.name,
            "path": self.path,
            "size": self.size,
            "is_folder": self.is_folder,
            "parent_id": self.parent_id,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "modified_at": self.modified_at.isoformat() if self.modified_at else None,
            "md5": self.md5,
            "deleted_at": self.deleted_at.isoformat(),
            "expires_at": self.expires_at.isoformat() if self.expires_at else None
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "TrashItem":
        """从字典创建"""
        created_at = None
        if data.get("created_at"):
            created_at = datetime.fromisoformat(data["created_at"])
        
        modified_at = None
        if data.get("modified_at"):
            modified_at = datetime.fromisoformat(data["modified_at"])
        
        deleted_at = datetime.fromisoformat(data["deleted_at"])
        
        expires_at = None
        if data.get("expires_at"):
            expires_at = datetime.fromisoformat(data["expires_at"])
        
        return cls(
            file_id=data["file_id"],
            name=data["name"],
            path=data["path"],
            size=data["size"],
            is_folder=data["is_folder"],
            parent_id=data.get("parent_id"),
            created_at=created_at,
            modified_at=modified_at,
            md5=data.get("md5"),
            deleted_at=deleted_at,
            expires_at=expires_at
        )